//
// Created by lxinp on 2022/8/10.
//

#include <iostream>
#include "queue.h"
#include "assert.h"


template<typename T>
Queue<T>::Queue() : max_size(4) {
    q = new T[max_size];
    front = back = 0;
}


template<typename T>
void Queue<T>::resize() {
    int old_size = size();
    T* temp = q;
    q = new T[max_size*2];
    for (int i=0; i<old_size; i++) {
        q[i] = temp[(i + front) % max_size];
    }
    max_size *= 2;
    front = 0, back = front + old_size;
    delete[] temp;
}


template<typename T>
void Queue<T>::enqueue(const T& data) {
    if (is_full()) resize();
    q[back] = data;
    back = (back + 1) % max_size;
}


template<typename T>
T Queue<T>::dequeue() {
    assert(!is_empty());
    T ret = q[front];
    front = (front + 1) % max_size;
    return ret;
}


template<typename T>
bool Queue<T>::is_empty() const {
    return (front == back);
}


template<typename T>
bool Queue<T>::is_full() const {
    return (front == (back + 1) % max_size);
}


template<typename T>
int Queue<T>::size() const {
    return (back - front) % max_size;
}


template<typename T>
void Queue<T>::print() const {
    std::cout << "[";
    //int curr = front;
    for (int i = front; i!=back;) {
        std::cout << q[i];
        if (i != (back - 1) % max_size) std::cout << ", ";
        i = (i + 1) % max_size;
    }
    std::cout << "]" << std::endl;
}


template<typename T>
Queue<T>::~Queue() {
    delete[] q;
}


template class Queue<int>;
